package com.punai.dataanalysis.epdatakb.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.punai.common.core.domain.BaseEntity;
import com.punai.dataanalysis.epdatakb.bo.NG001.JtczRcf;
import com.punai.dataanalysis.epdatakb.bo.NG001.SjxyfxBasic;
import com.punai.dataanalysis.epdatakb.service.NG001.NG001SjxyfxService;
import com.punai.dataanalysis.epdatakb.service.SjxyfxService;
import com.punai.dataanalysis.epdatakb.vo.DataAnalysisVo;
import com.punai.dataanalysis.ng001.constants.Ng001Constants;
import com.punai.externalccb.constants.CCBConstants;
import com.punai.externalccb.domain.EcoCbsummary;
import com.punai.externalccb.mapper.EcoCbsummaryMapper;
import com.punai.prodatalibrary.domain.LibProject;
import com.punai.prodatalibrary.mapper.LibProjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
public class SjxyfxServiceImpl implements SjxyfxService {

    @Autowired
    private NG001SjxyfxService ng001SjxyfxService;
    @Autowired
    private EcoCbsummaryMapper ecoCbsummaryMapper;
    @Autowired
    private LibProjectMapper libProjectMapper;

    @Override
    public List<? extends BaseEntity> getDataList(DataAnalysisVo dataAnalysisVo) {
        int month = DateUtil.month(new Date());
        dataAnalysisVo.setOneMonth(month == 0);
        List<SjxyfxBasic> basicAndCzCbInfo = ng001SjxyfxService.getBasicAndCzCbInfo(dataAnalysisVo);

        if (CollUtil.isEmpty(basicAndCzCbInfo)) {
            return new ArrayList<>();
        }

        for (SjxyfxBasic sjxyfxBasic : basicAndCzCbInfo) {
            sjxyfxBasic.setId(IdUtil.fastUUID());
        }
        List<String> proCodes = basicAndCzCbInfo.stream().map(SjxyfxBasic::getProCode)
                .filter(StrUtil::isNotBlank).collect(Collectors.toList());
        Map<String, List<EcoCbsummary>> hjMap = new HashMap<>();
        Map<String, String> projectMap = new HashMap<>();
        if (CollUtil.isNotEmpty(proCodes)) {
            // 取 开累目标成本
            // 取 本年目标成本
            List<LibProject> libProjects = libProjectMapper.selectList(
                    Wrappers.<LibProject>lambdaQuery()
                            .select(LibProject::getId,LibProject::getPmproinfoid)
                            .in(LibProject::getPmproinfoid, proCodes)
            );

            projectMap = libProjects.stream().collect(Collectors.toMap(LibProject::getPmproinfoid, LibProject::getId));
            Collection<String> values = projectMap.values();
            ArrayList<String> proIds = new ArrayList<>(values);
            if (CollUtil.isNotEmpty(proIds)) {
                List<EcoCbsummary> hjList = ecoCbsummaryMapper.selectList(
                        Wrappers.<EcoCbsummary>lambdaQuery()
                                .select(EcoCbsummary::getId,EcoCbsummary::getProId,EcoCbsummary::getTargetnottotal)
                                .in(EcoCbsummary::getProId, proIds)
                                .eq(EcoCbsummary::getStagetype, CCBConstants.CCB_TYPE.MBZRCB.getCode())
                                .eq(EcoCbsummary::getBidnodeid, 1)
                                .eq(EcoCbsummary::getPid, 0)
                                .eq(EcoCbsummary::getName, "合计")
                );
                hjMap = hjList.stream().collect(Collectors.groupingBy(EcoCbsummary::getProId));
            }
        }



        for (SjxyfxBasic sjxyfxBasic : basicAndCzCbInfo) {
            String proCode = sjxyfxBasic.getProCode();
            String proId = projectMap.get(proCode);
            if (StrUtil.isNotBlank(proId)) {
                List<EcoCbsummary> orDefault = hjMap.getOrDefault(proId, new ArrayList<>());
                BigDecimal cbTotal = orDefault.stream().map(EcoCbsummary::getTargetnottotal).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);//目标成本
                sjxyfxBasic.setKlmbcb(cbTotal);
                sjxyfxBasic.setBnmbcb(cbTotal);
            }
        }

        List<SjxyfxBasic> roots = new ArrayList<>();

        // 组 结构  求取利润值  利润率
        Map<String, List<SjxyfxBasic>> gsGroup = basicAndCzCbInfo.stream().collect(Collectors.groupingBy(SjxyfxBasic::getGs));
        for (Map.Entry<String, List<SjxyfxBasic>> gsGroupItem : gsGroup.entrySet()) {
            String gsKey = gsGroupItem.getKey();
            SjxyfxBasic gsBo = new SjxyfxBasic();
            gsBo.setId(IdUtil.fastUUID());
            gsBo.setKeyName(gsKey);
            roots.add(gsBo);
            List<SjxyfxBasic> gsBochildren = gsBo.getChildren();

            List<SjxyfxBasic> gsValue = gsGroupItem.getValue();
            Map<String, List<SjxyfxBasic>> xmbGroup = gsValue.stream().collect(Collectors.groupingBy(SjxyfxBasic::getXmb));
            for (Map.Entry<String, List<SjxyfxBasic>> xmbGroupItem : xmbGroup.entrySet()) {
                String xmbKey = xmbGroupItem.getKey();
                SjxyfxBasic xmbBo = new SjxyfxBasic();
                xmbBo.setId(IdUtil.fastUUID());
                xmbBo.setKeyName(xmbKey);
                gsBochildren.add(xmbBo);
                List<SjxyfxBasic> xmbChildren = xmbBo.getChildren();
                List<SjxyfxBasic> xmbValue = xmbGroupItem.getValue();
                for (SjxyfxBasic sjxyfxBasic : xmbValue) {
                    setLrLrl(sjxyfxBasic);
                    xmbChildren.add(sjxyfxBasic);
                }
                calcHz(xmbBo);
                calcPm(xmbChildren);
            }
            calcHz(gsBo);
            calcPm(gsBochildren);
        }
        calcPm(roots);
        fgxpx(roots);
        return roots;
    }

    /**
     * 分公司排序
     * @param roots
     */
    private void fgxpx(List<SjxyfxBasic> roots) {
        if (CollUtil.isNotEmpty(roots)) {
            roots.forEach(item -> item.setKeyNameOrder(Ng001Constants.CompanyOrderEnum.getOrderForType(item.getKeyName())));
            // 按照Order字段进行排序
            roots.sort(Comparator.comparingInt(SjxyfxBasic::getKeyNameOrder));
        }
    }

    private void calcPm(List<SjxyfxBasic> children) {
        if (CollUtil.isNotEmpty(children)) {
            children.sort(Comparator.comparing(SjxyfxBasic::getBnlrl,Comparator.reverseOrder()));
            for (int i = 0; i < children.size(); i++) {
                SjxyfxBasic bo = children.get(i);
                bo.setBnlrlpm(i+1);
            }
            children.sort(Comparator.comparing(SjxyfxBasic::getLjlrl,Comparator.reverseOrder()));
            for (int i = 0; i < children.size(); i++) {
                SjxyfxBasic bo = children.get(i);
                bo.setLhlrlpm(i+1);
            }
        }
    }

    private void calcHz(SjxyfxBasic bo) {

        BigDecimal ljcz = BigDecimal.ZERO;
        BigDecimal bncz = BigDecimal.ZERO;
        BigDecimal ljcb = BigDecimal.ZERO;
        BigDecimal bncb = BigDecimal.ZERO;
        BigDecimal klmbcb = BigDecimal.ZERO;
        BigDecimal bnmbcb = BigDecimal.ZERO;

        List<SjxyfxBasic> children = bo.getChildren();
        if (CollUtil.isNotEmpty(children)) {
            for (SjxyfxBasic child : children) {
                ljcz =  NumberUtil.add(   ljcz   ,child.getLjcz()    );
                bncz =  NumberUtil.add(   bncz   ,child.getBncz()    );
                ljcb =  NumberUtil.add(   ljcb   ,child.getLjcb()    );
                bncb =  NumberUtil.add(   bncb   ,child.getBncb()    );
                klmbcb =  NumberUtil.add( klmbcb ,child.getKlmbcb()    );
                bnmbcb =  NumberUtil.add( bnmbcb ,child.getBnmbcb()    );
            }
            bo.setLjcz(ljcz);
            bo.setBncz(bncz);
            bo.setLjcb(ljcb);
            bo.setBncb(bncb);
            bo.setKlmbcb(klmbcb);
            bo.setBnmbcb(bnmbcb);
        }
        setLrLrl(bo);
    }

    private void setLrLrl(SjxyfxBasic sjxyfxBasic) {

        // 累计利润 = 累计产值-累计成本
        BigDecimal ljcz = sjxyfxBasic.getLjcz();
        if (ljcz == null) {
            ljcz = BigDecimal.ZERO;
        }
        BigDecimal ljcb = sjxyfxBasic.getLjcb();
        BigDecimal ljlr = NumberUtil.sub(ljcz, ljcb);
        sjxyfxBasic.setLjrl(ljlr);

        // 累计利润率 = 累计利润/累计产值
        if(ljcz != null && BigDecimal.ZERO.compareTo(ljcz) != 0) {
            BigDecimal div = NumberUtil.div(ljlr, ljcz);
            BigDecimal ljlrl = NumberUtil.mul(div, 100).setScale(2, RoundingMode.HALF_UP);
            sjxyfxBasic.setLjlrl(ljlrl);
        } else {
            sjxyfxBasic.setLjlrl(BigDecimal.ZERO);
        }

        // 本年利润 = 本年产值-本年成本
        BigDecimal bncz = sjxyfxBasic.getBncz();
        if (bncz == null) {
            bncz = BigDecimal.ZERO;
        }
        BigDecimal bncb = sjxyfxBasic.getBncb();
        BigDecimal bnlr = NumberUtil.sub(bncz, bncb);
        sjxyfxBasic.setBnlr(bnlr);
        // 本年利润率 = 本年利润/本年产值
        if(bncz != null && BigDecimal.ZERO.compareTo(bncz) != 0) {
            BigDecimal div = NumberUtil.div(bnlr, bncz);
            BigDecimal bnlrl = NumberUtil.mul(div, 100).setScale(2, RoundingMode.HALF_UP);
            sjxyfxBasic.setBnlrl(bnlrl);
        } else {
            sjxyfxBasic.setBnlrl(BigDecimal.ZERO);
        }
    }


}
